home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / os20 / wb / toolmanager2_0.lha / ToolManager / Source / prefs / iconwindow.c < prev    next >
C/C++ Source or Header  |  1992-09-26  |  20KB  |  702 lines

  1. /*
  2.  * iconwindow.c  V2.0
  3.  *
  4.  * icon edit window handling
  5.  *
  6.  * (c) 1990-1992 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Icon node */
  12. struct IconNode {
  13.                  struct Node  in_Node;
  14.                  ULONG        in_Flags;
  15.                  char        *in_Exec;
  16.                  char        *in_Image;
  17.                  char        *in_Sound;
  18.                  LONG         in_XPos;
  19.                  LONG         in_YPos;
  20.                 };
  21.  
  22. /* Window data */
  23. static struct Gadget *gl;             /* Gadget list */
  24. static struct Window *w;              /* Window */
  25. static struct MsgPort *wp;            /* Window user port */
  26. static UWORD ww,wh;                   /* Window size */
  27. static struct IconNode *CurrentNode;
  28. static struct Gadget *CurrentGadget;
  29. static ULONG CurrentGadgetNum;
  30. static BOOL ReqOpen;
  31. #define WINDOW_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|\
  32.                       CHECKBOXIDCMP|STRINGIDCMP|TEXTIDCMP)
  33.  
  34. /* Gadget data */
  35. #define GAD_NAME_STR   0 /* Gadgets with labels */
  36. #define GAD_EXEC_BUT   1
  37. #define GAD_IMAGE_BUT  2
  38. #define GAD_SOUND_BUT  3
  39. #define GAD_XPOS_INT   4
  40. #define GAD_YPOS_INT   5
  41.  
  42. #define GAD_EXEC_TXT   6
  43. #define GAD_IMAGE_TXT  7
  44. #define GAD_SOUND_TXT  8
  45.  
  46. #define GAD_POSITION   9 /* Cycle gadget */
  47.  
  48. #define GAD_SHOWNAME  10 /* Checkbox gadget */
  49.  
  50. #define GAD_OK        11
  51. #define GAD_CANCEL    12
  52. #define GADGETS       13
  53. static struct GadgetData gdata[GADGETS];
  54.  
  55. /* Gadget tags */
  56. static struct TagItem nametags[]={GTST_String,   NULL,
  57.                                   GTST_MaxChars, 100,
  58.                                   TAG_DONE};
  59.  
  60. static struct TagItem exectags[]={GTTX_Text,   NULL,
  61.                                   GTTX_Border, TRUE,
  62.                                   TAG_DONE};
  63.  
  64. static struct TagItem imagetags[]={GTTX_Text,   NULL,
  65.                                    GTTX_Border, TRUE,
  66.                                    TAG_DONE};
  67.  
  68. static struct TagItem soundtags[]={GTTX_Text,   NULL,
  69.                                    GTTX_Border, TRUE,
  70.                                    TAG_DONE};
  71.  
  72. static char *cyclelabels[3]={NULL, NULL, NULL};
  73. static struct TagItem cycletags[]={GTCY_Labels, cyclelabels,
  74.                                    GTCY_Active, 0,
  75.                                    TAG_DONE};
  76.  
  77. static struct TagItem xpostags[]={GTIN_Number,   0,
  78.                                   GTIN_MaxChars, 10,
  79.                                   TAG_DONE};
  80.  
  81. static struct TagItem ypostags[]={GTIN_Number,   0,
  82.                                   GTIN_MaxChars, 10,
  83.                                   TAG_DONE};
  84.  
  85. static struct TagItem showntags[]={GTCB_Checked, FALSE,
  86.                                    TAG_DONE};
  87.  
  88. /* Init icon edit window */
  89. void InitIconEditWindow(UWORD left, UWORD fheight)
  90. {
  91.  ULONG labwidth,gadwidth,cycwidth,cbwidth,butwidth;
  92.  ULONG strheight=fheight+2;
  93.  ULONG i,tmp,yadd;
  94.  struct GadgetData *gd;
  95.  
  96.  /* Init strings */
  97.  gdata[GAD_NAME_STR].name  =AppStrings[MSG_WINDOW_NAME_GAD];
  98.  gdata[GAD_EXEC_BUT].name  =AppStrings[MSG_WINDOW_EXEC_GAD];
  99.  gdata[GAD_IMAGE_BUT].name =AppStrings[MSG_WINDOW_IMAGE_GAD];
  100.  gdata[GAD_SOUND_BUT].name =AppStrings[MSG_WINDOW_SOUND_GAD];
  101.  gdata[GAD_XPOS_INT].name  =AppStrings[MSG_WINDOW_LEFTEDGE_GAD];
  102.  gdata[GAD_YPOS_INT].name  =AppStrings[MSG_WINDOW_TOPEDGE_GAD];
  103.  cyclelabels[0]            =AppStrings[MSG_WINDOW_POSITION_OPEN_LABEL];
  104.  cyclelabels[1]            =AppStrings[MSG_WINDOW_POSITION_CLOSE_LABEL];
  105.  gdata[GAD_SHOWNAME].name  =AppStrings[MSG_ICONWIN_SHOWNAME_GAD];
  106.  gdata[GAD_OK].name        =AppStrings[MSG_WINDOW_OK_GAD];
  107.  gdata[GAD_CANCEL].name    =AppStrings[MSG_WINDOW_CANCEL_GAD];
  108.  
  109.  /* Calculate maximum label width for string gadgets */
  110.  labwidth=0;
  111.  gd=&gdata[GAD_NAME_STR];
  112.  for (i=GAD_NAME_STR; i<=GAD_YPOS_INT; i++, gd++)
  113.   if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > labwidth)
  114.    labwidth=tmp;
  115.  labwidth+=2*INTERWIDTH;
  116.  
  117.  /* Calculate minimum string gadget width */
  118.  gadwidth=TextLength(&TmpRastPort,AppStrings[MSG_ICONWIN_NEWNAME],
  119.                      strlen(AppStrings[MSG_ICONWIN_NEWNAME]))+2*INTERWIDTH;
  120.  
  121.  /* Calculate minimum window width */
  122.  ww=labwidth+gadwidth+2*INTERWIDTH;
  123.  
  124.  /* Calculate maximum cyclegadget width */
  125.  {
  126.   char **s;
  127.  
  128.   cycwidth=0;
  129.   s=cyclelabels;
  130.   for (i=0; i<=1; i++, s++)
  131.    if ((tmp=TextLength(&TmpRastPort,*s,strlen(*s))) > cycwidth)
  132.     cycwidth=tmp;
  133.   cycwidth+=5*INTERWIDTH;
  134.  }
  135.  if ((tmp=cycwidth+INTERWIDTH) > ww) ww=tmp;
  136.  
  137.  /* Calculate checkbox label width */
  138.  gd=&gdata[GAD_SHOWNAME];
  139.  cbwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name))+INTERWIDTH
  140.          +CHKBOXWIDTH;
  141.  if ((tmp=cbwidth+INTERWIDTH) > ww) ww=tmp;
  142.  
  143.  /* Calculate button gadgets width */
  144.  gd=&gdata[GAD_OK];
  145.  butwidth=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  146.  gd++;
  147.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > butwidth)
  148.   butwidth=tmp;
  149.  butwidth+=2*INTERWIDTH;
  150.  if ((tmp=2*(butwidth+INTERWIDTH)) > ww) ww=tmp;
  151.  
  152.  /* window height */
  153.  wh=9*fheight+10*INTERHEIGHT+12;
  154.  
  155.  /* Init gadgets */
  156.  gd=gdata;
  157.  tmp=WindowTop+INTERHEIGHT;
  158.  gadwidth=ww-labwidth-2*INTERWIDTH; /* String gadget width */
  159.  i=labwidth;
  160.  labwidth+=left+INTERWIDTH;
  161.  yadd=strheight+INTERHEIGHT;
  162.  
  163.  /* Name string gadget */
  164.  gd->type=STRING_KIND;
  165.  gd->flags=PLACETEXT_LEFT;
  166.  gd->tags=nametags;
  167.  gd->left=labwidth;
  168.  gd->top=tmp;
  169.  gd->width=gadwidth;
  170.  gd->height=strheight;
  171.  tmp+=yadd;
  172.  
  173.  /* Exec object button gadget */
  174.  gd++;
  175.  gd->type=BUTTON_KIND;
  176.  gd->flags=PLACETEXT_IN;
  177.  gd->left=left;
  178.  gd->top=tmp;
  179.  gd->width=i;
  180.  gd->height=strheight;
  181.  tmp+=yadd;
  182.  
  183.  /* Image object button gadget */
  184.  gd++;
  185.  gd->type=BUTTON_KIND;
  186.  gd->flags=PLACETEXT_IN;
  187.  gd->left=left;
  188.  gd->top=tmp;
  189.  gd->width=i;
  190.  gd->height=strheight;
  191.  tmp+=yadd;
  192.  
  193.  /* Sound object button gadget */
  194.  gd++;
  195.  gd->name=AppStrings[MSG_WINDOW_SOUND_GAD];
  196.  gd->type=BUTTON_KIND;
  197.  gd->flags=PLACETEXT_IN;
  198.  gd->left=left;
  199.  gd->top=tmp;
  200.  gd->width=i;
  201.  gd->height=strheight;
  202.  tmp+=yadd+fheight+INTERHEIGHT;
  203.  
  204.  /* Leftedge integer gadget */
  205.  gd++;
  206.  gd->type=INTEGER_KIND;
  207.  gd->flags=PLACETEXT_LEFT;
  208.  gd->tags=xpostags;
  209.  gd->left=labwidth;
  210.  gd->top=tmp;
  211.  gd->width=gadwidth;
  212.  gd->height=strheight;
  213.  tmp+=yadd;
  214.  
  215.  /* TopEdge integer gadget */
  216.  gd++;
  217.  gd->type=INTEGER_KIND;
  218.  gd->flags=PLACETEXT_LEFT;
  219.  gd->tags=ypostags;
  220.  gd->left=labwidth;
  221.  gd->top=tmp;
  222.  gd->width=gadwidth;
  223.  gd->height=strheight;
  224.  
  225.  /* Exec object text gadget */
  226.  tmp=WindowTop+yadd+INTERHEIGHT;
  227.  gd++;
  228.  gd->type=TEXT_KIND;
  229.  gd->tags=exectags;
  230.  gd->left=labwidth;
  231.  gd->top=tmp;
  232.  gd->width=gadwidth;
  233.  gd->height=strheight;
  234.  tmp+=yadd;
  235.  
  236.  /* Image object text gadget */
  237.  gd++;
  238.  gd->type=TEXT_KIND;
  239.  gd->tags=imagetags;
  240.  gd->left=labwidth;
  241.  gd->top=tmp;
  242.  gd->width=gadwidth;
  243.  gd->height=strheight;
  244.  tmp+=yadd;
  245.  
  246.  /* Sound object text gadget */
  247.  gd++;
  248.  gd->type=TEXT_KIND;
  249.  gd->tags=soundtags;
  250.  gd->left=labwidth;
  251.  gd->top=tmp;
  252.  gd->width=gadwidth;
  253.  gd->height=strheight;
  254.  tmp+=yadd;
  255.  
  256.  /* Position cycle gadget */
  257.  gd++;
  258.  gd->type=CYCLE_KIND;
  259.  gd->flags=PLACETEXT_IN;
  260.  gd->tags=cycletags;
  261.  gd->left=left;
  262.  gd->top=tmp;
  263.  gd->width=ww-INTERWIDTH;
  264.  gd->height=fheight;
  265.  
  266.  /* Showname checkbox gadget */
  267.  tmp=WindowTop+7*fheight+8*INTERHEIGHT+12;
  268.  gd++;
  269.  gd->type=CHECKBOX_KIND;
  270.  gd->flags=PLACETEXT_RIGHT;
  271.  gd->tags=showntags;
  272.  gd->left=(ww-cbwidth-INTERWIDTH)/2+left;
  273.  gd->top=tmp;
  274.  gd->width=CHKBOXWIDTH;
  275.  gd->height=fheight;
  276.  tmp+=fheight+INTERHEIGHT;
  277.  
  278.  /* OK button gadget */
  279.  gd++;
  280.  gd->type=BUTTON_KIND;
  281.  gd->flags=PLACETEXT_IN;
  282.  gd->left=left;
  283.  gd->top=tmp;
  284.  gd->width=butwidth;
  285.  gd->height=fheight;
  286.  
  287.  /* Cancel button gadget */
  288.  gd++;
  289.  gd->type=BUTTON_KIND;
  290.  gd->flags=PLACETEXT_IN;
  291.  gd->left=ww-butwidth-INTERWIDTH+left;
  292.  gd->top=tmp;
  293.  gd->width=butwidth;
  294.  gd->height=fheight;
  295. }
  296.  
  297. /* Free icon node */
  298. void FreeIconNode(struct Node *node)
  299. {
  300.  struct IconNode *in=node;
  301.  char *s;
  302.  
  303.  if (s=in->in_Node.ln_Name) free(s);
  304.  if (s=in->in_Exec) free(s);
  305.  if (s=in->in_Image) free(s);
  306.  if (s=in->in_Sound) free(s);
  307.  
  308.  /* Free node */
  309.  FreeMem(in,sizeof(struct IconNode));
  310. }
  311.  
  312. /* Copy image node */
  313. struct Node *CopyIconNode(struct Node *node)
  314. {
  315.  struct IconNode *in,*orignode=node;
  316.  
  317.  /* Alloc memory for exec node */
  318.  if (in=AllocMem(sizeof(struct IconNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  319.  
  320.   /* Got an old node? */
  321.   if (orignode) {
  322.    /* Yes, copy it */
  323.    if ((!orignode->in_Node.ln_Name || (in->in_Node.ln_Name=
  324.                                         strdup(orignode->in_Node.ln_Name))) &&
  325.        (!orignode->in_Exec || (in->in_Exec=strdup(orignode->in_Exec))) &&
  326.        (!orignode->in_Image || (in->in_Image=strdup(orignode->in_Image))) &&
  327.        (!orignode->in_Sound || (in->in_Sound=strdup(orignode->in_Sound)))) {
  328.     /* Copy flags & numbers */
  329.     in->in_Flags=orignode->in_Flags;
  330.     in->in_XPos=orignode->in_XPos;
  331.     in->in_YPos=orignode->in_YPos;
  332.     return(in);
  333.    }
  334.   } else
  335.    /* No, set defaults */
  336.    if (in->in_Node.ln_Name=strdup(AppStrings[MSG_ICONWIN_NEWNAME])) {
  337.     /* Set flags */
  338.     in->in_Flags=ICPOF_SHOWNAME;
  339.  
  340.     /* Return pointer to new node */
  341.     return(in);
  342.    }
  343.  
  344.   FreeIconNode((struct Node *) in);
  345.  }
  346.  /* Call failed */
  347.  return(NULL);
  348. }
  349.  
  350. /* Activate gadget and save pointer to it */
  351. static ActivateAndSetGadget(ULONG num)
  352. {
  353.  CurrentGadget=gdata[num].gadget;
  354.  ActivateGadget(CurrentGadget,w,NULL);
  355. }
  356.  
  357. /* Open icon edit window */
  358. BOOL OpenIconEditWindow(struct Node *node, struct Window *parent)
  359. {
  360.  /* Copy node */
  361.  if (CurrentNode=CopyIconNode(node)) {
  362.   /* Set tags */
  363.   nametags[0].ti_Data=CurrentNode->in_Node.ln_Name;
  364.   exectags[0].ti_Data=CurrentNode->in_Exec;
  365.   imagetags[0].ti_Data=CurrentNode->in_Image;
  366.   soundtags[0].ti_Data=CurrentNode->in_Sound;
  367.   xpostags[0].ti_Data=CurrentNode->in_XPos;
  368.   ypostags[0].ti_Data=CurrentNode->in_YPos;
  369.   showntags[0].ti_Data=(CurrentNode->in_Flags & ICPOF_SHOWNAME)!=0;
  370.  
  371.   /* Create gadgets */
  372.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  373.    /* Open window */
  374.    if (w=OpenWindowTags(NULL,WA_Left,parent->LeftEdge,
  375.                              WA_Top,parent->TopEdge+WindowTop,
  376.                              WA_InnerWidth,ww,
  377.                              WA_InnerHeight,wh,
  378.                              WA_AutoAdjust,TRUE,
  379.                              WA_Title,AppStrings[MSG_ICONWIN_TITLE],
  380.                              WA_PubScreen,PublicScreen,
  381.                              WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  382.                                       WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  383.                                       WFLG_ACTIVATE,
  384.                              TAG_DONE)) {
  385.     /* Add gadgets to window */
  386.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  387.     RefreshGList(gl,w,NULL,(UWORD) -1);
  388.     GT_RefreshWindow(w,NULL);
  389.  
  390.     /* Activate name string gadget */
  391.     ActivateAndSetGadget(GAD_NAME_STR);
  392.  
  393.     /* Set local variables */
  394.     w->UserPort=IDCMPPort;
  395.     w->UserData=HandleIconEditWindowIDCMP;
  396.     ModifyIDCMP(w,WINDOW_IDCMP);
  397.     CurrentWindow=w;
  398.     ReqOpen=FALSE;
  399.  
  400.     /* All OK. */
  401.     return(TRUE);
  402.    }
  403.    FreeGadgets(gl);
  404.   }
  405.   FreeIconNode((struct Node *) CurrentNode);
  406.  }
  407.  /* Call failed */
  408.  return(FALSE);
  409. }
  410.  
  411. /* Close icon edit window */
  412. static void CloseIconEditWindow(void)
  413. {
  414.  /* Free resources */
  415.  if (MoveWindowPtr) CloseMoveWindow();
  416.  RemoveGList(w,gl,(UWORD) -1);
  417.  CloseWindowSafely(w);
  418.  FreeGadgets(gl);
  419. }
  420.  
  421. /* If move window open, move it to new position */
  422. static void MoveMoveWindow(void)
  423. {
  424.  /* Move window open? */
  425.  if (MoveWindowPtr) {
  426.   ULONG x,y;
  427.  
  428.   /* Read current position */
  429.   x=((struct StringInfo *) gdata[GAD_XPOS_INT].gadget->SpecialInfo)->LongInt;
  430.   y=((struct StringInfo *) gdata[GAD_YPOS_INT].gadget->SpecialInfo)->LongInt;
  431.  
  432.   /* Move move window */
  433.   MoveWindow(MoveWindowPtr,x-MoveWindowPtr->LeftEdge+WBXOffset,
  434.                            y-MoveWindowPtr->TopEdge+WBYOffset);
  435.  }
  436. }
  437.  
  438. /* Handle icon edit window IDCMP events */
  439. void *HandleIconEditWindowIDCMP(struct IntuiMessage *msg)
  440. {
  441.  struct Node *NewNode=NULL;
  442.  
  443.  /* Which IDCMP class? */
  444.  switch (msg->Class) {
  445.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  446.                             FreeIconNode((struct Node *) CurrentNode);
  447.                             break;
  448.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  449.                             GT_EndRefresh(w,TRUE);
  450.                             break;
  451.   case IDCMP_GADGETUP:
  452.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  453.     case GAD_NAME_STR:  ActivateAndSetGadget(GAD_XPOS_INT);
  454.                         break;
  455.     case GAD_EXEC_BUT:  if (!ReqOpen) {
  456.                          /* Save gadget number */
  457.                          CurrentGadgetNum=GAD_EXEC_TXT;
  458.  
  459.                          /* Open list requester */
  460.                          if (OpenListRequester(LISTREQ_EXEC,w)) {
  461.                           /* Disable window */
  462.                           DisableWindow(w);
  463.  
  464.                           /* Set update function */
  465.                           UpdateWindow=UpdateIconEditWindow;
  466.                           ReqOpen=TRUE;
  467.                          } else
  468.                           /* Activate old string gadget */
  469.                           ActivateGadget(CurrentGadget,w,NULL);
  470.                         }
  471.                         break;
  472.     case GAD_IMAGE_BUT: if (!ReqOpen) {
  473.                          /* Save gadget number */
  474.                          CurrentGadgetNum=GAD_IMAGE_TXT;
  475.  
  476.                          /* Open list requester */
  477.                          if (OpenListRequester(LISTREQ_IMAGE,w)) {
  478.                           /* Disable window */
  479.                           DisableWindow(w);
  480.  
  481.                           /* Set update function */
  482.                           UpdateWindow=UpdateIconEditWindow;
  483.                           ReqOpen=TRUE;
  484.                          } else
  485.                           /* Activate old string gadget */
  486.                           ActivateGadget(CurrentGadget,w,NULL);
  487.                         }
  488.                         break;
  489.     case GAD_SOUND_BUT: if (!ReqOpen) {
  490.                          /* Save gadget number */
  491.                          CurrentGadgetNum=GAD_SOUND_TXT;
  492.  
  493.                          /* Open list requester */
  494.                          if (OpenListRequester(LISTREQ_SOUND,w)) {
  495.                           /* Disable window */
  496.                           DisableWindow(w);
  497.  
  498.                           /* Set update function */
  499.                           UpdateWindow=UpdateIconEditWindow;
  500.                           ReqOpen=TRUE;
  501.                          } else
  502.                           /* Activate old string gadget */
  503.                           ActivateGadget(CurrentGadget,w,NULL);
  504.                         }
  505.                         break;
  506.     case GAD_XPOS_INT:  MoveMoveWindow();
  507.                         ActivateAndSetGadget(GAD_YPOS_INT);
  508.                         break;
  509.     case GAD_YPOS_INT:  MoveMoveWindow();
  510.                         ActivateAndSetGadget(GAD_NAME_STR);
  511.                         break;
  512.     case GAD_EXEC_TXT:
  513.                         break;
  514.     case GAD_IMAGE_TXT:
  515.                         break;
  516.     case GAD_SOUND_TXT:
  517.                         break;
  518.     case GAD_POSITION:  /* Move window open? */
  519.                         if (MoveWindowPtr)
  520.                          /* Yes. Close move window */
  521.                          CloseMoveWindow();
  522.                         else {
  523.                          /* No. Open it! */
  524.                          MoveWindowOffX=WBXOffset;
  525.                          MoveWindowOffY=WBYOffset;
  526.  
  527.                          /* Open move window */
  528.                          OpenMoveWindow(w,gdata[GAD_XPOS_INT].gadget,
  529.                                           gdata[GAD_YPOS_INT].gadget);
  530.                         }
  531.  
  532.                         /* Activate old string gadget */
  533.                         ActivateGadget(CurrentGadget,w,NULL);
  534.                         break;
  535.     case GAD_SHOWNAME:  /* Toggle flag */
  536.                         CurrentNode->in_Flags^=ICPOF_SHOWNAME;
  537.  
  538.                         /* Activate old string gadget */
  539.                         ActivateGadget(CurrentGadget,w,NULL);
  540.                         break;
  541.     case GAD_OK: {
  542.      char *s;
  543.  
  544.      /* Free old string */
  545.      if (s=CurrentNode->in_Node.ln_Name) free(s);
  546.  
  547.      /* Duplicate new string */
  548.      if ((CurrentNode->in_Node.ln_Name=
  549.            DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1) {
  550.       /* Copy integer gadget values */
  551.       CurrentNode->in_XPos=
  552.        ((struct StringInfo *) gdata[GAD_XPOS_INT].gadget->SpecialInfo)->LongInt;
  553.       CurrentNode->in_YPos=
  554.        ((struct StringInfo *) gdata[GAD_YPOS_INT].gadget->SpecialInfo)->LongInt;
  555.  
  556.       NewNode=CurrentNode;
  557.      } else {
  558.       /* Couldn't copy strings */
  559.       NewNode=(struct Node *) -1;
  560.       CurrentNode->in_Node.ln_Name=NULL;
  561.       FreeIconNode((struct Node *) CurrentNode);
  562.      }
  563.     }
  564.     break;
  565.     case GAD_CANCEL:    NewNode=(struct Node *) -1;
  566.                         FreeIconNode((struct Node *) CurrentNode);
  567.                         break;
  568.    }
  569.    break;
  570.  }
  571.  
  572.  /* Close window? */
  573.  if (NewNode) {
  574.   /* Yes. But first reply message!!! */
  575.   GT_ReplyIMsg(msg);
  576.   CloseIconEditWindow();
  577.  }
  578.  
  579.  return(NewNode);
  580. }
  581.  
  582. /* Update Icon edit window */
  583. void UpdateIconEditWindow(void *data)
  584. {
  585.  /* Got data? */
  586.  if (data != LREQRET_CANCEL) {
  587.   char *new;
  588.  
  589.   /* Selected something? */
  590.   new=(data == LREQRET_NOSELECT) ? NULL : ((struct Node *) data)->ln_Name;
  591.  
  592.   /* Duplicate name */
  593.   if (!new || (new=strdup(new))) {
  594.    char *old;
  595.  
  596.    /* Which object? */
  597.    switch (CurrentGadgetNum) {
  598.     case GAD_EXEC_TXT:  /* Set new Exec name */
  599.                         old=CurrentNode->in_Exec;
  600.                         CurrentNode->in_Exec=new;
  601.                         break;
  602.     case GAD_IMAGE_TXT: /* Set new Image name */
  603.                         old=CurrentNode->in_Image;
  604.                         CurrentNode->in_Image=new;
  605.                         break;
  606.     case GAD_SOUND_TXT: /* Set new Sound name */
  607.                         old=CurrentNode->in_Sound;
  608.                         CurrentNode->in_Sound=new;
  609.                         break;
  610.    }
  611.  
  612.    /* Free old string */
  613.    if (old) free(old);
  614.  
  615.    /* Set new text */
  616.    GT_SetGadgetAttrs(gdata[CurrentGadgetNum].gadget,w,NULL,GTTX_Text,new,
  617.                                                            TAG_DONE);
  618.   }
  619.  }
  620.  
  621.  /* Activate old string gadget */
  622.  ActivateGadget(CurrentGadget,w,NULL);
  623.  
  624.  /* Enable window */
  625.  EnableWindow(w,WINDOW_IDCMP);
  626.  
  627.  /* Restore update function pointer */
  628.  UpdateWindow=UpdateMainWindow;
  629.  CurrentWindow=w;
  630.  ReqOpen=FALSE;
  631. }
  632.  
  633. /* Read TMIC IFF chunk into Icon node */
  634. struct Node *ReadIconNode(UBYTE *buf)
  635. {
  636.  struct IconNode *in;
  637.  
  638.  /* Allocate memory for node */
  639.  if (in=AllocMem(sizeof(struct IconNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  640.   struct IconPrefsObject *ipo=buf;
  641.   ULONG sbits=ipo->ipo_StringBits;
  642.   UBYTE *ptr=ipo+1;
  643.  
  644.   if ((!(sbits & ICPO_NAME) || (in->in_Node.ln_Name=GetConfigStr(&ptr))) &&
  645.       (!(sbits & ICPO_EXEC) || (in->in_Exec=GetConfigStr(&ptr))) &&
  646.       (!(sbits & ICPO_IMAGE) || (in->in_Image=GetConfigStr(&ptr))) &&
  647.       (!(sbits & ICPO_SOUND) || (in->in_Sound=GetConfigStr(&ptr)))) {
  648.    /* Copy flags & values */
  649.    in->in_Flags=ipo->ipo_Flags;
  650.    in->in_XPos=ipo->ipo_XPos;
  651.    in->in_YPos=ipo->ipo_YPos;
  652.  
  653.    /* All OK. */
  654.    return(in);
  655.   }
  656.  
  657.   /* Call failed */
  658.   FreeIconNode((struct Node *) in);
  659.  }
  660.  return(NULL);
  661. }
  662.  
  663. /* Write Icon node to TMIC IFF chunk */
  664. BOOL WriteIconNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  665. {
  666.  struct IconNode *in=node;
  667.  struct IconPrefsObject *ipo=buf;
  668.  ULONG sbits=0;
  669.  UBYTE *ptr=ipo+1;
  670.  
  671.  /* Copy strings */
  672.  if (PutConfigStr(in->in_Node.ln_Name,&ptr)) sbits|=ICPO_NAME;
  673.  if (PutConfigStr(in->in_Exec,&ptr)) sbits|=ICPO_EXEC;
  674.  if (PutConfigStr(in->in_Image,&ptr)) sbits|=ICPO_IMAGE;
  675.  if (PutConfigStr(in->in_Sound,&ptr)) sbits|=ICPO_SOUND;
  676.  
  677.  /* set string bits */
  678.  ipo->ipo_StringBits=sbits;
  679.  
  680.  /* Copy flags & values */
  681.  ipo->ipo_Flags=in->in_Flags;
  682.  ipo->ipo_XPos=in->in_XPos;
  683.  ipo->ipo_YPos=in->in_YPos;
  684.  
  685.  /* calculate length */
  686.  sbits=ptr-buf;
  687.  
  688.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  689.  
  690.  /* Open chunk */
  691.  if (PushChunk(iff,0,ID_TMIC,sbits)) return(FALSE);
  692.  
  693.  /* Write chunk */
  694.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  695.  
  696.  /* Close chunk */
  697.  if (PopChunk(iff)) return(FALSE);
  698.  
  699.  /* All OK. */
  700.  return(TRUE);
  701. }
  702.